#ifndef skyString_h__
#define skyString_h__
#include "./skyPtr.h"
#include "./skyObject.h"
namespace Sky
{
class StringBuilder;
typedef RefPtr<StringBuilder> StringBuilderPtr;
class String : public Object
{
	DECL_RTTI1(String,Object);
private:
	class stringNode
	{
	protected:
		friend class String;
		const Char* _str;
		i32 _size;
	public:
		stringNode(const Char* str,i32 size):_str(str)
		{
			if(size == -1)
				_size = String::getStringLength(str) + sizeof(Char);
			else
				_size = size;
		}
	};
public:
	class staticString : public stringNode
	{
	public:
		staticString(const Char* const str,i32 size = -1):stringNode(str,size){}
	};
	class dynamicString : public stringNode
	{
	public:
		dynamicString(const Char* str,i32 size = -1):stringNode(str,size){}
	};
	class managedString : public stringNode
	{
	public:
		managedString(Char* str,i32 size = -1):stringNode(str,size){}
		managedString(i32 size):stringNode((Char*)Memory::alloc(size),size)
		{
			(const_cast<Char*>(_str))[0] = _XC('\0');
		}
	};
	static i32 getStringLength(const Char* str)
	{
		//return (i32)skyStrlen(str);
		i32 l = 0;
		if(str == vNull)return 0;
		Char* p = const_cast<Char*>(str);
		while(*p)
		{
			 l++;
			 p++;
		}
		return l;
	}
	static Bool compare(const StringPtr& str1,const StringPtr& str2);
	static Bool compare(const Char* str1,const Char* str2);
public:
	String():_str(NULL),_len(0){}
	~String();
	typedef Char* const refferString;
	String(const Char* str,i32 size = -1,i32 len = -1);
	String(staticString& str,i32 len = -1);
	String(dynamicString& str,i32 len = -1);
	String(managedString& str,i32 len = -1);
	String(String& str);
	Bool endWith(String& str){return vFalse;}
	Void toLower(){return;}
	virtual StringPtr toString(StringPtr str = StringPtr());
	Void operator =(String& str);
	u32 getLength();
	u32 getSize();
	Void resetLength();
	Char* toCharString()const;
	i32 rFind(String& str){return 0;}
	StringPtr subStr(i32 h,i32 e){return vNull;} 
	Bool copyFrom(const Char* str, i32 len = -1);
	Void clear();
	String* operator ->(){return this;}
private:
	Char* _str;
	i32   _len;
	i32   _size;
};	
//////////////////////////////////////////////////////////////////////////
class StringBuilder : public Object
{
	DECL_RTTI1(StringBuilder,Object);
public:
	StringBuilder();
	~StringBuilder();
	StringBuilder* append(StringPtr& str);
	StringBuilder* append(String::staticString& str);
	StringBuilder* append(String::dynamicString& str);
	StringBuilder* append(const Char* str,i32 len = -1);
	StringPtr toString(String* str = vNull);
	void clear();
private:
	class StringNode : public Memory
	{
	public:
		StringPtr str;
		StringNode* next;
	};
	StringNode* _head;
	StringNode* _rear;
	u32 _totalLength;
};
}
#endif // skyString_h__
